﻿using Cofe.Core.Logger;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Cofe.Core
{
    public class CofeSystemWatcher : IEventListener<CofeSystemEventArgs>, IDisposable
    {
        #region Constructor
        public CofeSystemWatcher(string watchPath = null, string[] listeningListers = null)
        {
            if (watchPath != null)
            {
                string pattern = string.Format("{0}.*", watchPath).Replace(@"\", @"\\");
                this.ListenPatterns = new string[] { pattern };
            }
            else
                this.ListenPatterns = new string[] { ".*" };

            this.ListenListers = listeningListers;

            
        }
        #endregion

        #region Methods        

        public void DispatchEvent(IEnumerable<IEventLog<CofeSystemEventArgs>> eventsRecorded)
        {
            if (_enableRaisingEvents)
                foreach (var e in eventsRecorded)
                    DispatchEvent(e.Sender, e.EventArgs);
        }

        public void DispatchEvent(object sender, CofeSystemEventArgs args)
        {
            switch (args.ChangeType)
            {
                case ModifiedAction.Created: NotifyCreated(sender, args); break;
                case ModifiedAction.Changed: NotifyChanged(sender, args); break;
                case ModifiedAction.Deleted: NotifyDeleted(sender, args); break;
                case ModifiedAction.Renamed:
                    if (args is CofeRenameEventArgs)
                        NotifyRenamed(sender, args as CofeRenameEventArgs); break;
            }
        }

        public void NotifyChanged(object sender, CofeSystemEventArgs args)
        {
            Changed(sender, args);
        }

        public void NotifyCreated(object sender, CofeSystemEventArgs args)
        {
            Created(sender, args);
        }

        public void NotifyDeleted(object sender, CofeSystemEventArgs args)
        {
            Deleted(sender, args);
        }

        public void NotifyRenamed(object sender, CofeRenameEventArgs args)
        {
            Renamed(sender, args);
        }

        private void enableChanged(bool value)
        {
            if (value != _enableRaisingEvents)
                if (value)
                {
                    _cts = new CancellationTokenSource();  //this.CancellationToken
                    CofeServices.EventHub.RegisterEventListener<CofeSystemEventArgs>(this);
                }
                else
                {
                    _cts.Cancel();
                }

            _enableRaisingEvents = value;
        }

        public void Dispose()
        {
            _cts.Cancel();
        }


        ~CofeSystemWatcher()
        {
            Dispose();
        }

        #endregion

        #region Data

        private bool _enableRaisingEvents = false;
        private CancellationTokenSource _cts = null;

        #endregion

        #region Public Properties

        public string[] ListenPatterns { get; private set; }
        public string[] ListenListers { get; private set; }
        public CancellationToken CancellationToken { get { return _cts.Token; } }

        public bool EnableRaisingEvents
        {
            get { return _enableRaisingEvents; }
            set { enableChanged(value); }
        }

        public event EventHandler<CofeSystemEventArgs> Changed = (o, e) => { };
        public event EventHandler<CofeSystemEventArgs> Created = (o, e) => { };
        public event EventHandler<CofeSystemEventArgs> Deleted = (o, e) => { };
        public event EventHandler<CofeRenameEventArgs> Renamed = (o, e) => { };

        #endregion


    }
}
